export const debounce = <ARG>(fn: (arg: ARG) => void, delay?: number): (arg: ARG) => void => {
    let timer: NodeJS.Timeout | null = null
    if (delay == null) {
        delay = 200
    }
    return (arg: ARG) => {
        timer && clearTimeout(timer)
        timer = setTimeout(() => {
            fn(arg)
        }, delay)
    }
}

// 第一次执行直接运行
export const debounceOptimistic = <ARG>(fn: (arg: ARG) => void, delay: number = 300): (arg: ARG) => void => {
    let timer: NodeJS.Timeout | null = null;
    let isWaiting = false;

    return (arg: ARG) => {
        if (isWaiting) {
            clearTimeout(timer!);
        } else {
            // 如果不是在等待状态，立即执行函数
            fn(arg);
        }
        isWaiting = true;
        timer = setTimeout(() => {
            isWaiting = false;
        }, delay);
    };
};

export const debounceNoArg = (fn: () => void, delay?: number): () => void => {
    let timer: NodeJS.Timeout | null = null
    if (delay == null) {
        delay = 200
    }
    return () => {
        timer && clearTimeout(timer)
        timer = setTimeout(() => {
            fn()
        }, delay)
    }
}

const doubleClickWait = new Set()

/**
 * 将单击转换为双击，需要在300ms内两次调用该函数，才能执行回调函数
 * @param fn 需要被双击执行的函数
 * @param key 标志位，标记双击按钮
 * @param param 函数的参数
 */
export const toDoubleClick = <T>(fn: (param?: T) => void, key: string, param?: T) => {
    if (doubleClickWait.has(key)) {
        fn(param)
        return
    }
    doubleClickWait.add(key)
    setTimeout(() => {
        doubleClickWait.delete(key)
    }, 300)
}

/**
 * 通过文件路径获取文件名
 * @param link 文件路径
 */
export const getFileName = (link: string) => {
    if (link == null) {
        return "空"
    }
    return link.substring(link.lastIndexOf('/') + 1)
}

export const formatTime = (date: Date) => {
    return `${date.getFullYear()}年${date.getMonth()}月${date.getDate()}日` +
        ` ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
}
